package com.hktf.corelib.utils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5 {
	   
    public static char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    public static String ecodeByMD5(byte[] pwd) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(
                    pwd);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Huh, MD5 should be supported?", e);
        } catch (Exception e) {
            throw new RuntimeException("Huh, UTF-8 should be supported?", e);
        }
        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10)
                hex.append("0");
            hex.append(Integer.toHexString(b & 0xFF));
        }
        return hex.toString();
    }
   
    public static String toHexString(byte[] b) {  
        StringBuilder sb = new StringBuilder(b.length * 2);  
        for (int i = 0; i < b.length; i++) {  
            sb.append(hexChar[(b[i] & 0xf0) >>> 4]);  
            sb.append(hexChar[b[i] & 0x0f]);  
        }  
        return sb.toString();  
    }  
   
    public static String getHash(String fileName, String hashType) throws Exception {  
        InputStream fis = new FileInputStream(fileName);  
        byte[] buffer = new byte[1024];  
        MessageDigest md5 = MessageDigest.getInstance(hashType);  
        int numRead = 0;  
        while ((numRead = fis.read(buffer)) > 0) { // 瓶颈  
            md5.update(buffer, 0, numRead);  
        }  
        fis.close();  
        return toHexString(md5.digest());  
    }  
   
    public static String getHashNio(String fileName, String hashType) throws Exception {  
        FileInputStream fStream = null;  
        String hash = null;  
        try {  
            MessageDigest md5 = MessageDigest.getInstance(hashType);  
            fStream = new FileInputStream(fileName);  
            FileChannel fChannel = fStream.getChannel();  
            ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);  
            for (int count = fChannel.read(buffer); count != -1; count = fChannel.read(buffer)) {  
                buffer.flip();  
                md5.update(buffer);  
                if (!buffer.hasRemaining()) {  
                    // System.out.println("count:"+count);  
                    buffer.clear();  
                }  
            }  
            hash = toHexString(md5.digest());  
   
        } catch (NoSuchAlgorithmException e) {  
            e.printStackTrace();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                if (fStream != null)  
                    fStream.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        return hash;  
    }  
   
    public static void main(String[] args) throws Exception {  
        String fileName = "G:/QQDownload/The.Man.From.Earth.2007.mkv";  
        long t1 = System.currentTimeMillis();  
   
        System.out.println(MD5.getHash(fileName, "MD5"));  
        long t2 = System.currentTimeMillis();  
        System.out.println("耗时：" + (t2 - t1) + " ms");  
   
        System.out.println(MD5.getHashNio(fileName, "MD5"));  
        System.out.println("耗时：" + (System.currentTimeMillis() - t2) + " ms");  
    }  
   
}
